//
#pragma once
//
namespace xwpl {
	//
	class _fpu_stack
	{
	public:
		__forceinline _fpu_stack()
		{
		}
		__forceinline _fpu_stack(_fpu_stack &)
		{
		}
		__forceinline _fpu_stack(int init)
		{
			__asm FILd DWORD PTR [init];
		}
		__forceinline _fpu_stack(long init)
		{
			__asm FILd DWORD PTR [init];
		}
		__forceinline _fpu_stack(__int64 init)
		{
			__asm FILd QWORD PTR [init];
		}
		__forceinline _fpu_stack(float init)
		{
			__asm FLd DWORD PTR [init];
		}
		__forceinline _fpu_stack(double init)
		{
			__asm FLd QWORD PTR [init];
		}
		__forceinline _fpu_stack & operator = (_fpu_stack &)
		{
		}
	};
	//
	__declspec(align(2)) class long_double
	{
	private:
		unsigned char data[10];
	public:
		__forceinline long_double()
		{
			__asm FLdZ;
			__asm Mov ECX, this;
			__asm FStP TBYTE PTR [ECX];
		}
		__forceinline long_double(_fpu_stack)
		{
			__asm Mov ECX, this;
			__asm FStP TBYTE PTR [ECX];
		}
		__forceinline operator _fpu_stack()
		{
			__asm Mov ECX, this;
			__asm FLd TBYTE PTR [ECX];
		}
		__forceinline friend bool operator == (_fpu_stack left, _fpu_stack right)
		{
			__asm FComPP;
			__asm FStSW AX;
			__asm Sahf;
			__asm Je label_condition_true;
			__asm Xor EAX, EAX;
			__asm Jmp label_exit;
			__asm label_condition_true:;
			__asm Mov EAX, 1;
			__asm label_exit:; 
		}
		__forceinline friend bool operator != (_fpu_stack left, _fpu_stack right)
		{
			__asm FComPP;
			__asm FStSW AX;
			__asm Sahf;
			__asm Jne label_condition_true;
			__asm Xor EAX, EAX;
			__asm Jmp label_exit;
			__asm label_condition_true:;
			__asm Mov EAX, 1;
			__asm label_exit:;
		}
		__forceinline friend bool operator < (_fpu_stack left, _fpu_stack right)
		{
			__asm FComPP;
			__asm FStSW AX;
			__asm Sahf;
			__asm Jg label_condition_true;
			__asm Xor EAX, EAX;
			__asm Jmp label_exit;
			__asm label_condition_true:;
			__asm Mov EAX, 1;
			__asm label_exit:;
		}
		__forceinline friend bool operator > (_fpu_stack left, _fpu_stack right)
		{
			__asm FComPP;
			__asm FStSW AX;
			__asm Sahf;
			__asm Jl label_condition_true;
			__asm Xor EAX, EAX;
			__asm Jmp label_exit;
			__asm label_condition_true:;
			__asm Mov EAX, 1;
			__asm label_exit:;
		}
		__forceinline friend bool operator <= (_fpu_stack left, _fpu_stack right)
		{
			__asm FComPP;
			__asm FStSW AX;
			__asm Sahf;
			__asm Jge label_condition_true;
			__asm Xor EAX, EAX;
			__asm Jmp label_exit;
			__asm label_condition_true:;
			__asm Mov EAX, 1;
			__asm label_exit:;
		}
		__forceinline friend bool operator >= (_fpu_stack left, _fpu_stack right)
		{
			__asm FComPP;
			__asm FStSW AX;
			__asm Sahf;
			__asm Jle label_condition_true;
			__asm Xor EAX, EAX;
			__asm Jmp label_exit;
			__asm label_condition_true:;
			__asm Mov EAX, 1;
			__asm label_exit:;
		}
		__forceinline long_double & operator = (const _fpu_stack &)
		{
			__asm Mov ECX, this;
			__asm FStP TBYTE PTR [ECX];
			return *this;
		}
		__forceinline friend _fpu_stack operator + (_fpu_stack left, _fpu_stack right)
		{
			__asm FAddP ST(1), ST(0)
				return _fpu_stack();
		}
		__forceinline friend _fpu_stack operator - (_fpu_stack left, _fpu_stack right)
		{
			__asm FSubP ST(1), ST(0)
				return _fpu_stack();
		}
		__forceinline friend _fpu_stack operator * (_fpu_stack left, _fpu_stack right)
		{
			__asm FMulP ST(1), ST(0)
				return _fpu_stack();
		}
		__forceinline friend _fpu_stack operator / (_fpu_stack left, _fpu_stack right)
		{
			__asm FDivP ST(1), ST(0)
				return _fpu_stack();
		}
	};
	//
}// namespace xwpl
//
// End of file
//